Skip to content

db: enforce foreign keys, and ship the licence package.json claims - #154

Merged
ralyodio merged 1 commit into
mainfrom
fix/fk-and-license
Jul 31, 2026
Merged

db: enforce foreign keys, and ship the licence package.json claims#154
ralyodio merged 1 commit into
mainfrom
fix/fk-and-license

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Two things that were true on paper and not in fact.

Foreign keys were never enforced

SQLite ignores every REFERENCES clause unless PRAGMA foreign_keys = ON is set — per connection — and nothing here ever set it. So these have all been decorative:

moshpit_names.user_id           ON DELETE CASCADE
moshpit_name_purchases.user_id  ON DELETE CASCADE
moshpit_name_pins.user_id       ON DELETE CASCADE
sessions.user_id                ON DELETE CASCADE

Deleting a user left their names, purchases, published keys and sessions behind, pointing at a row that no longer exists. A published key outliving its owner is a key nobody can revoke.

Verified against a real database — before: 1 name, 1 pin. After DELETE FROM users: 0 and 0.

Set once at import and not awaited: every statement goes through the same client and libSQL serialises on the connection, so the PRAGMA is on the wire before anything depending on it. A failure is logged rather than thrown — the app still works without it, it just enforces less.

The risk in turning this on is old inserts referencing rows that don't exist, which would now fail rather than quietly succeed. 292 tests say there are none.

The licence was claimed but not shipped

package.json has said "license": "MIT" with no LICENSE file in the repo — so the claim was unenforceable and GitHub reported the project all-rights-reserved. The file is moshcoding's verbatim, same copyright holder.

🤖 Generated with Claude Code

Two things that were true on paper and not in fact.

SQLite ignores every REFERENCES clause unless `PRAGMA foreign_keys = ON` is set,
per connection, and nothing here ever set it. So the ON DELETE CASCADE on
moshpit_names.user_id, moshpit_name_purchases.user_id, moshpit_name_pins.user_id
and sessions.user_id have all been decorative: deleting a user left their names,
purchases, published keys and sessions behind, pointing at a row that no longer
exists. A published key outliving its owner is a key nobody can revoke.

Set once at import and not awaited — every statement goes through the same
client and libSQL serialises on the connection, so the PRAGMA is on the wire
before anything that depends on it. A failure is logged rather than thrown: the
app still works without it, it just enforces less.

The risk in turning this on is old inserts that reference rows which do not
exist, which would now fail rather than quietly succeed. 292 tests say there
are none.

package.json has claimed "license": "MIT" with no LICENSE file in the repo, so
the claim was unenforceable and GitHub reported the project as all-rights-
reserved. The file is moshcoding's verbatim, same copyright holder.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

vu1nz Security Review

0 finding(s) in PR #?

No security issues found.

@ralyodio
ralyodio merged commit a436530 into main Jul 31, 2026
3 checks passed
@ralyodio
ralyodio deleted the fix/fk-and-license branch July 31, 2026 16:43
@ralyodio ralyodio mentioned this pull request Aug 1, 2026
ralyodio added a commit that referenced this pull request Aug 1, 2026
install.sh resolves releases/latest, so the sixteen commits merged since
v0.13.3 have been sitting on main unreachable — including a fix for a page
that locks browsers up.

The headline is the pit. /pit rendered every ending an account held and a form
per name under each, with no bound on either: at 50 endings x 100 names that
was 3.1 MiB of HTML and 36,082 DOM elements, and it managed to jam a browser
with no script on the page at all (#167). It now draws a window and says what
it is not drawing — 173 KiB, 1,926 elements — with a filter box over the top
that takes `eggs` as a substring and `def*` as a glob, debounced against the
API (#168).

The namespace also stopped being the one part of the product a script could
not touch: /api/moshpit/* now accepts the same API key /api/me and
/api/sessions already did (#169), and /pit/dns finally documents the
TronBrowser route for machines whose DNS is not theirs to change (#165).

  moshcode: foreign keys are enforced, and the licence package.json
  claims actually ships (#154)
  cli: help aliases exit 0 (#157), invalid integration commands fail (#160),
  `--` is honoured (#159), a BOM before a shebang no longer breaks (#158)
  skills: engines with no skills primitive are reported, not dropped (#166);
  `--name` requires a value (#156)
  mcp: an unsupported flag is rejected rather than registered as the server
  name (#164)
  pit: the namespace rules are vendored again with a drift test holding them
  to the published package (#161, #162, #163)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant